package com.train.user.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.train.common.annotation.Anonymous;
import com.train.common.constant.Constants;
import com.train.common.core.controller.BaseController;
import com.train.common.core.domain.AjaxResult;
import com.train.common.core.domain.entity.SysUser;
import com.train.common.core.domain.model.LoginUser;
import com.train.common.utils.file.MinioUtils;
import com.train.framework.web.service.TokenService;
import com.train.system.service.ISysUserService;
import com.train.user.domain.WechatAuth;
import com.train.user.service.WechatLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.http.MediaType;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.security.PermitAll;
import java.util.Arrays;


/**
 * 微信登录Controller
 *
 * @author train
 */
@RestController
@RequestMapping("/user/wechat/login")
public class WechatLoginController extends BaseController {

    public static final String WECHAT_LOGIN_URL = "https://open.weixin.qq.com/connect/qrconnect";
    // 建议将 AppID 和 AppSecret 配置在 application.properties/yml 中
    @Value("${wechat.appid}")
    private String APP_ID;

    @Value("${wechat.secret}")
    private String APP_SECRET;

    @Autowired
    WechatLoginService wechatLoginService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private MinioUtils minioUtils;


    private final RestTemplate restTemplate;


    // Spring 推荐的注入方式：构造器注入
    public WechatLoginController(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }


    // 1. 获取 Access Token 的接口 URL
    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/jscode2session"
            + "?appid={appid}"
            + "&secret={secret}"
            + "&js_code={code}"
            + "&grant_type=authorization_code";

    // 2. 获取用户信息的接口 URL
    private static final String USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo"
            + "?access_token={access_token}"
            + "&openid={openid}";



    /**
     * 微信登录回调接口：处理微信授权返回的 code
     */
    @Anonymous
    @GetMapping("/auth")
    public AjaxResult wechatAuth(@RequestParam("code") String code) {


        // --- 1. 使用 code 换取 access_token 和 openid/unionid ---
        try {
            // 设置 Accept 头部为 application/json
            HttpHeaders headers = new HttpHeaders();
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
            HttpEntity<?> entity = new HttpEntity<>(headers);

            // 使用 Map 传递 URL 模板参数，避免手动拼接字符串
            ResponseEntity<String> tokenResponse = restTemplate.getForEntity(
                    ACCESS_TOKEN_URL,
                    String.class,
                    APP_ID,
                    APP_SECRET,
                    code
            );

            // 手动将 JSON 字符串转换为 WechatAuth 对象
            ObjectMapper objectMapper = new ObjectMapper();
            WechatAuth auth = objectMapper.readValue(tokenResponse.getBody(), WechatAuth.class);

            if (auth != null && auth.getErrcode() != null && auth.getErrcode() != 0) {
                // 自动映射后，可以直接判断错误码
                logger.error("微信返回错误: " + auth.getErrcode());
                return AjaxResult.error("微信返回错误: " + auth.getErrmsg());
            }


            LoginUser loginUser = wechatLoginService.wechatAuth(auth);

            // 生成token
            String token = tokenService.createToken(loginUser);

            AjaxResult ajaxResult = AjaxResult.success("微信登录成功");
            ajaxResult.put(Constants.TOKEN, token);
            return ajaxResult;

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("系统异常: " + e.getMessage());
        }
    }

    /**
     * 查询当前登录用户信息
     */
    @GetMapping("/profile")
    public AjaxResult profile() {
        LoginUser loginUser = getLoginUser();
        SysUser user = loginUser.getUser();
        SysUser sysUser = userService.selectUserById(user.getUserId());
        user.setAvatar(sysUser.getAvatar());
        user.setPassword(null);

        AjaxResult ajax = AjaxResult.success(user);
        ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
        ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
        return ajax;
    }

    /**
     * 修改当前登录用户信息
     */

    @PutMapping("/profile")
    public AjaxResult updateProfile(@RequestBody SysUser user) {
        LoginUser loginUser = getLoginUser();
        SysUser currentUser = loginUser.getUser();
        
        currentUser.setNickName(user.getNickName());
        currentUser.setEmail(user.getEmail());
        currentUser.setPhonenumber(user.getPhonenumber());
        currentUser.setSex(user.getSex());
        currentUser.setAvatar(user.getAvatar());
        
        if (userService.updateUserProfile(currentUser) > 0) {
            // 更新成功后更新token中的用户信息
            loginUser.setUser(currentUser);
            tokenService.refreshToken(loginUser);
            return AjaxResult.success("用户信息修改成功");
        }
        return AjaxResult.error("修改用户信息失败");
    }
    
    /**
     * 头像上传接口
     */
    @PostMapping("/avatar")
    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) {
        try {
            if (!file.isEmpty()) {
                LoginUser loginUser = getLoginUser();
                // 上传头像到MinIO
                String objectName = minioUtils.uploadAvatar(file);
                
                // 获取头像访问URL
                String avatarUrl = minioUtils.getPresignedObjectUrl(objectName);
                
                // 更新用户头像信息
                if (userService.updateUserAvatar(loginUser.getUserId(), avatarUrl)) {
                    AjaxResult ajax = AjaxResult.success();
                    ajax.put("imgUrl", avatarUrl);
                    // 更新缓存用户头像
                    loginUser.getUser().setAvatar(avatarUrl);
                    tokenService.setLoginUser(loginUser);
                    return ajax;
                }
            }
            return error("上传图片异常，请联系管理员");
        } catch (Exception e) {
            return error("上传头像失败: " + e.getMessage());
        }
    }
}